/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.motoo.core;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 
 * @author linfengqi
 * @version 1.0  May 13, 2009
 * @param <V>
 */
public abstract class AbstractExecutor<V> {
	
	public final static int DEFAULT_CORE_POOL_SIZE = 1;
	public final static int DEFAULT_MAXIMUM_POOL_SIZE = 100;
	public final static int DEFAULT_KEEP_ALIVE_TIME = 0;
	private long keepAliveTime;
	private int corePoolSize;
	private int maximumPoolSize;
	private int poolSize;
	private int largestPoolSize;
	private long completedTaskCount;
	protected ThreadPoolExecutor executorService;
	
	public AbstractExecutor() {
		this(DEFAULT_CORE_POOL_SIZE, DEFAULT_MAXIMUM_POOL_SIZE, DEFAULT_KEEP_ALIVE_TIME);
	}
	
	public AbstractExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
		if (corePoolSize <= 0) corePoolSize = DEFAULT_CORE_POOL_SIZE;
		if (maximumPoolSize <= 0) maximumPoolSize = DEFAULT_MAXIMUM_POOL_SIZE;
		if (keepAliveTime < 0) keepAliveTime = DEFAULT_KEEP_ALIVE_TIME;
		this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.keepAliveTime = keepAliveTime;
		executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
				keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
	}
	
	public abstract Future<V> submit(Runnable task);
	
	public abstract Future<V> submit(Callable<V> task);

	public long getKeepAliveTime() {
		return keepAliveTime;
	}

	public void setKeepAliveTime(long keepAliveTime) {
		this.keepAliveTime = keepAliveTime;
		executorService.setKeepAliveTime(keepAliveTime, TimeUnit.MILLISECONDS);
	}

	public int getCorePoolSize() {
		return corePoolSize;
	}

	public void setCorePoolSize(int corePoolSize) {
		this.corePoolSize = corePoolSize;
		executorService.setCorePoolSize(corePoolSize);
	}

	public int getMaximumPoolSize() {
		return maximumPoolSize;
	}

	public void setMaximumPoolSize(int maximumPoolSize) {
		this.maximumPoolSize = maximumPoolSize;
		executorService.setMaximumPoolSize(maximumPoolSize);
	}

	public int getPoolSize() {
		poolSize = executorService.getPoolSize();
		return poolSize;
	}

	public int getLargestPoolSize() {
		largestPoolSize = executorService.getLargestPoolSize();
		return largestPoolSize;
	}

	public long getCompletedTaskCount() {
		completedTaskCount = executorService.getCompletedTaskCount();
		return completedTaskCount;
	}

}
